home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / lcppb.zip / LCPPLIB.ZIP / WINDOW.CPP < prev    next >
C/C++ Source or Header  |  1991-07-08  |  12KB  |  325 lines

  1. // window.cpp -- Window class
  2.  
  3. //#include <disp.h>
  4. #include "disp.h"
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include "error.h"
  8. #include "window.h"
  9.  
  10. #define FALSE  0
  11. #define TRUE   1
  12.  
  13. extern disp_numrows;       // Gain access to normally hidden
  14. extern disp_numcols;       //  display package variables.
  15.  
  16. /* -- Define and initialize the static class member field, which
  17. indicates whether the display package has been initialized.  This
  18. variable is global--it is shared by all variables of the cwindow
  19. class. But, because it's declared private to the class, only class
  20. member functions have access to it. */
  21.  
  22. int cwindow::dispInitialized = FALSE;
  23.  
  24. /* -- Private routine (not a member of the cwindow class). Display a
  25. string at an absolute row and column position using the specified
  26. attribute. Limit length of string to len characters. Ideally, this
  27. routine should display all possible ASCII symbols--it should not
  28. respond to control codes such as carriage returns and line feeds. */
  29.  
  30. void putsat(int row, int col, int len, unsigned attr, char *s)
  31.   unsigned char buffer[264];
  32.   int i, j;
  33.  
  34.   if (len == 0) return;
  35.   for (i = 0, j = 0; i < len; i++, j += 2) {
  36.     buffer[j] = s[i];
  37.     buffer[j + 1] = attr;
  38.   }
  39.   disp_pokebox((unsigned *)&buffer, row, col, row, col + len - 1);
  40. }
  41.  
  42. /* -- Program must call the class static startup function to 
  43. initialize the display package (or another display library if porting
  44. the code). Because startup is a static member function, it can access
  45. only static data members of the class. It has no access whatsoever to
  46. other data fields in cwindow class objects. */
  47.  
  48. void cwindow::startup(void)
  49. {
  50.   if (!dispInitialized) {      // If not initialized yet
  51.     disp_open();               //  then initialize display
  52.     disp_hidecursor();         // Turn off system cursor
  53.     dispInitialized = TRUE;    // Set the static flag
  54.   }
  55. }
  56.  
  57. /* -- Program must call the class static shutDown function to
  58. deinitialize the display package. Failure to call this routine could
  59. lead to display problems after the program ends. (This may or may not
  60. be the case after porting the code to a system that doesn't use the
  61. Zortech display package.) */
  62.  
  63. void cwindow::shutDown(void)
  64. {
  65.   if (dispInitialized) {        // If previously initialized:
  66.     disp_move(disp_numrows - 1, 0 ); // Set cursor to bottom row
  67.     disp_showcursor();               // Display cursor
  68.     disp_close();                    // Shut down display package
  69.     dispInitialized = FALSE;         // Reset the static flag
  70.   }
  71. }
  72.  
  73. /* -- Create and return pointer to a buffer for saving text behind
  74. window. Returns NULL if enough memory is not available. */
  75.  
  76. unsigned *cwindow::saveBuf(void)
  77. {
  78. //  return malloc((ws.height * ws.width) * sizeof(unsigned));
  79.   return (unsigned *)malloc((ws.height * ws.width) * sizeof(unsigned));
  80. }
  81.  
  82. /* -- Perform various common initialization steps for all new
  83. windows. Called by all class constructors. Aborts program if window
  84. class startup function was not called, or if the class was shut down.
  85. If you add new constructors to the cwindow class, be sure to call this
  86. routine, or failing that, at least test the dispInitialized flag and
  87. take appropriate actions if the flag is false. */
  88.  
  89. void cwindow::commonInits(void)
  90. {
  91.   if (!dispInitialized)           // Test if display initialized
  92.     error(ERRWININIT);            // Halt or report error if not
  93.   cr = cc = 0;                    // Home logical cursor
  94.   save = NULL;                    // Text behind not saved
  95.   isOpen = FALSE;                 // window is not open
  96.   if (ws.row > disp_numrows - 3)  // Limit smallest window
  97.     ws.row = disp_numrows - 3;    //  to one row, one column
  98.   if (ws.col > disp_numcols - 3)
  99.     ws.col = disp_numcols - 3;
  100.   if (ws.width < 1) ws.width = 1; // window width must be >= 1
  101.   if (ws.height < 1) ws.height = 1; // window height must be >= 1
  102.   wbr = ws.row + ws.height - 1;   // window's bottom row number
  103.   wrc = ws.col + ws.width - 1;    // window's right column number
  104.   wca = ws.wtattr;                // Current attr = normal text
  105.   wtitle = NULL;                  // No window title (yet)
  106. }
  107.  
  108. /* -- Default constructor. Creates full-screen window. The save
  109. pointer is set to NULL, which causes the window not to save the text
  110. behind it. Because the default window is full screen, this saves at
  111. least 4K of memory. */
  112.  
  113. cwindow::cwindow()
  114. {
  115.   ws.row = ws.col = 0;            // Upper left corner
  116.   ws.width = disp_numcols;        // Full width of display
  117.   ws.height = disp_numrows;       // Full height of display
  118.   ws.wtattr = DISP_NORMAL;        // Normal text attribute
  119.   ws.wbattr = DISP_NORMAL;        // Normal border attribute
  120.   ws.whattr = DISP_REVERSEVIDEO;  // Highlight in reverse video
  121.   ws.wtype = 0;                   // Select double-line border
  122.   commonInits();                  // Do other init steps
  123. }
  124.  
  125. /* -- Alternate constructor. Allows sizing window and selecting 
  126. various attributes. Saves text behind window. */
  127.  
  128. cwindow::cwindow(winStruct &ws, const char *title)
  129. {
  130.   cwindow::ws = ws;
  131.   commonInits();
  132.   setTitle(title);
  133.   save = saveBuf();
  134. }
  135.  
  136. /* -- Destructor. Deallocates save-text buffer (if allocated). Note
  137. that it is legal to pass a NULL pointer to free, but it is not okay
  138. to do the same with delete--a minor inconsistency in this version of
  139. C++ that can lead to trouble. Deleting a NULL pointer may cause the
  140. program to crash. */
  141.  
  142. cwindow::~cwindow()
  143. {
  144.   if (isOpen) hideWindow();  // Close window if open
  145.   free(save);                // Dispose save buffer (if any)
  146.   if (wtitle) delete wtitle; // Dispose old title (if any)
  147. }
  148.  
  149. /* -- Display window outline and title if one was assigned. Called
  150. by showWindow and if the title is changed after window is opened. */
  151.  
  152. void cwindow::showOutline(void)
  153. {
  154.   int len;    // String length
  155.  
  156.   disp_box(ws.wtype, ws.wbattr, ws.row, ws.col, wbr, wrc);
  157.   if (wtitle != NULL) {
  158.     len = strlen(wtitle->getString());
  159.     if (len > 0) {
  160.       putsat(ws.row, ws.col + ((ws.width - len) / 2), len,
  161.         ws.wbattr, wtitle->getString());
  162.       gotorc(cr, cc);
  163.     }
  164.   }
  165. }
  166.  
  167. /* -- Save text behind window (optional), draw window's border, erase
  168. the contents. Cursor is positioned inside window at top left corner.
  169. The host program is expected to display the window's contents.
  170. Prevents accidentally opening an already open window, which would
  171. destroy the save buffer. */
  172.  
  173. void cwindow::showWindow()
  174. {
  175.   if (isOpen) return;  // Prevent multiple openings
  176.   if (save) disp_peekbox(save, ws.row, ws.col, wbr, wrc);
  177.   showOutline();
  178.   isOpen = TRUE;
  179.   gotorc(0, 0);
  180.   normalVideo();
  181.   eeow();
  182. }
  183.  
  184. /* -- Restore any saved text behind window and mark window closed. If
  185. there is no save buffer, the display will not change, although the
  186. window will still be closed. */
  187.  
  188. void cwindow::hideWindow()
  189. {
  190.   if (!isOpen) return; // Exit if window is closed
  191.   if (save) disp_pokebox(save, ws.row, ws.col, wbr, wrc);
  192.   isOpen = FALSE;
  193. }
  194.  
  195. /* -- Change window title. You may call this routine whether or not
  196. you specified a title when creating the window object. window may
  197. be open or closed. */
  198.  
  199. void cwindow::setTitle(const char *s)
  200. {
  201.   if (wtitle) delete wtitle;
  202.   wtitle = new strItem(s, ws.width - 2);
  203.   if (isOpen) showOutline();
  204. }
  205.  
  206. /* -- Assign new attributes to window. Use this function to move and
  207. resize windows, or just to change their colors, border types, etc.
  208. Selects normalVideo output. */
  209.  
  210. void cwindow::setInfo(winStruct &ws)
  211. {
  212.   int wasOpen = isOpen;
  213.  
  214.   if (isOpen) hideWindow();
  215.   if (save) delete save;
  216.   cwindow::ws = ws;
  217.   save = saveBuf();
  218.   if (wasOpen) {
  219.     normalVideo();
  220.     showWindow();
  221.   }
  222. }
  223.  
  224. /* -- Move cursor to position inside window border. Top left position
  225. is 0, 0 (home). Row and column values are relative to window
  226. boundaries. Note: Does not make system cursor visible--instead, this
  227. function prepares the location where text will appear for the next
  228. call to puts(). Cursor is allowed to rest on the right border, but
  229. otherwise must remain within the window's boundaries.*/
  230.  
  231. void cwindow::gotorc(int row, int col)
  232. {
  233.   if (!isOpen) return;       // Exit if window is closed
  234.   cr = row; cc = col;        // Save relative values
  235.   if (cc < 0) cc = 0;        // Prevent negative
  236.   if (cr < 0) cr = 0;        //  cursor positions
  237.   if (cc > ws.width - 2)
  238.     cc = ws.width - 2;      // Limit col to window width
  239.   if (cr > ws.height - 3)
  240.     cr = ws.height - 3;     // Limit row to window height
  241.   disp_move(ws.row + cr + 1, ws.col + cc + 1);
  242. }
  243.  
  244. /* -- Display string at current cursor position. String is truncated
  245. to fit within the window boundaries. Cursor is positioned at the end
  246. of the string. (It is possible for the cursor to be on the
  247. right border, but it is not possible to display text there.) */
  248.  
  249. void cwindow::puts(char *s)
  250. {
  251.   int len = strlen(s);          // String length
  252.   int nc = ws.width - cc - 2;   // Number chars right of cursor
  253.  
  254.   if (!isOpen) return;    // Exit if window is closed
  255.   if (nc <= 0) return;    // Exit if no space to cursor's right
  256.   if (len == 0) return;   // Exit if length of string is 0
  257.   if (len > nc) len = nc; // Truncate too-long strings
  258.   putsat(ws.row + cr + 1, ws.col + cc + 1, len, wca, s);
  259.   gotorc(cr, cc + len);   // Position cursor to end of string
  260. }
  261.  
  262. /* -- Scroll contents of current window up by the number of lines 
  263. specified in nrows. Blanks that many lines at bottom using the current
  264. display attribute. */
  265.  
  266. void cwindow::scrollUp(int nrows)
  267. {
  268.   if (!isOpen) return; // Exit if window is closed
  269.   disp_scroll(nrows, ws.row + 1, ws.col + 1, wbr - 1, wrc - 1, wca);
  270. }
  271.  
  272. /* -- Scroll contents of current window down by the number of lines 
  273. specified in nrows. Blanks that many lines at top using the current
  274. display attribute. */
  275.  
  276. void cwindow::scrollDown(int nrows)
  277. {
  278.   if (!isOpen) return; // Exit if window is closed
  279.   disp_scroll(-nrows, ws.row + 1, ws.col + 1, wbr - 1, wrc - 1, wca);
  280. }
  281.  
  282. /* -- Erase from current cursor position to end of line, that is, to
  283. just before the window's right border. Uses the current attribute for
  284. the blanked area. */
  285.  
  286. void cwindow::eeol(void)
  287. {
  288.   unsigned attr = wca * 256 + ' '; // Attribute for blank line
  289.   int nc = ws.width - cc - 3;      // Number of chars to erase
  290.   int acr = ws.row + cr + 1;       // Absolute cursor row
  291.   int acc = ws.col + cc + 1;       // Absolute cursor column
  292.  
  293.   if (!isOpen) return;    // Exit if window is closed
  294.   if (nc < 0) return;     // Exit if no space to cursor's right
  295.   disp_fillbox(attr, acr, acc, acr, acc + nc);
  296. }
  297.  
  298. /* -- Erase from current cursor position to end of window, that is,
  299. to just before the window's bottom border. Uses the current attribute
  300. for the blanked area. */
  301.  
  302. void cwindow::eeow(void)
  303. {
  304.   int ocr = cr;        // Save old cr (cursor row)
  305.   int occ = cc;        // Save old cc (cursor col)
  306.  
  307.   if (!isOpen) return;             // Exit if window is closed
  308.   eeol();                          // Erase to end of current line
  309.   while (++cr < ws.height - 2) {   // Erase other full lines if any
  310.     gotorc(cr, 0);
  311.     eeol();
  312.   }
  313.   cr = ocr;            // Restore saved cursor position
  314.   cc = occ;
  315. }
  316.  
  317.  
  318. // Copyright (c) 1990 by Tom Swan. All rights reserved
  319. // Revision 1.00    Date: 09/22/1990   Time: 12:33 am
  320.  
  321. // Revision 1.01    Date: 07/08/1991   Time: 05:41 pm
  322. // Converted for Borland C++ 2.0
  323.  
  324.